package org.agile4j.springframework.aop;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Arrays;

/**
 * 日志切面类
 * @author hyx
 *
 */
public class LogAspect {
	private static final Logger logger = LogManager.getLogger(LogAspect.class);

	/** 
     * 前置通知：在某连接点之前执行的通知，但这个通知不能阻止连接点前的执行 
     * @param jp 连接点：程序执行过程中的某一行为，例如，NewsServiceImpl.show()的调用或者抛出的异常行为 
     */  
    public void doBefore(JoinPoint jp) {
    	String strLog = "方法执行前记录日志: "  
                + jp.getTarget().getClass().getName() + "."  
                + jp.getSignature().getName(); 
        String args = null ;
        if(jp.getArgs() != null) {
        	args = Arrays.toString(jp.getArgs()) ;
			logger.info(strLog + "参数：{}", args);  
        } else {
        	logger.info(strLog); 
        }
    }
    
    /** 
     * 环绕通知：包围一个连接点的通知，可以在方法的调用前后完成自定义的行为，也可以选择不执行 
     * @param pjp 当前进程中的连接点 
     * @return 
     * @throws Throwable 
     */  
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {  
        long time = System.currentTimeMillis();  
        // 前
        // 个人认为这里可以加catch / 或者不使用
        Object retVal = pjp.proceed();  
        // 后
        time = System.currentTimeMillis() - time;
        logger.info("process time: " + time + " ms");  
        return retVal;  
    }
    
    /** 
     * 抛出异常后通知 ： 在方法抛出异常退出时执行的通知。 
     * @param jp 连接点：程序执行过程中的某一行为，例如，NewsServiceImpl.show()的调用或者抛出的异常行为 
     */  
    public void doAfter(JoinPoint jp) {  
    	String strLog ="方法执行后记录日志: "  
                + jp.getTarget().getClass().getName() + "."  
                + jp.getSignature().getName();  
        String args = null ;
        if(jp.getArgs() != null) {
        	args = Arrays.toString(jp.getArgs()) ;
        	logger.info(strLog+"参数：{}",args);  
        } else {
        	logger.info(strLog); 
        } 
    } 
}
